package com.cheer.websocket;

import com.alibaba.fastjson.JSONObject;
import com.cheer.bo.OpponentBO;
import com.cheer.dao.ExMatchUserDao;
import com.cheer.entity.ExMatchUserEntity;
import com.cheer.util.SpringContextUtil;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import javax.swing.*;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @author cheer
 */
@ServerEndpoint(value = "/ws/match", configurator = GetHttpSessionConfigurator.class)
@Component
@DependsOn("springContextUtil")
@Slf4j
public class MatchWebsocket {

    @Autowired
    private ExMatchUserDao exMatchUserDao;

    private static AtomicInteger websocketCount = new AtomicInteger(0);

    private Session session;

    private Long userId;

    private String username;

    private String headIcon;

    private Integer level;

    private Map<Integer, Integer> performance;

    private MatchWebsocket opponent;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        websocketCount.getAndIncrement();

        this.userId = (Long) config.getUserProperties().get("userId");
        this.session = session;

        ExMatchUserEntity user = exMatchUserDao.selectById(this.userId);

        if (user == null) {
            try {
                this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "用户不存在"));
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
            return;
        }

        this.username = user.getUsername();
        this.headIcon = user.getHeadIcon();
        this.level = user.getLevel();

        boolean isQueued = MatchListener.putUser(this);
        if (!isQueued) {
            try {
                this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "匹配人数过多"));
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    @OnClose
    public void onClose() {
        websocketCount.getAndDecrement();
    }

    @OnMessage
    public void onMessage(String jsonStr, Session session) {


        try {
            opponent.session.getBasicRemote().sendText(jsonStr);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    public static void main(String[] args) {
        System.out.println(Integer.toBinaryString(4));
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error(error.getMessage(), error);
    }

    public String getUsername() {
        return username;
    }

    public String getHeadIcon() {
        return headIcon;
    }

    public Integer getLevel() {
        return level;
    }

    public void findNoOpponent() {
        MatchMessage message = new MatchMessage();
        message.setType(MatchMessage.TypeEnum.FIND_NO_OPPONENT.getCode());

        try {
            session.getBasicRemote().sendText(JSONObject.toJSONString(message));
            session.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public void findOpponent(MatchWebsocket opponent) {
        this.opponent = opponent;

        MatchMessage message = new MatchMessage();
        message.setType(MatchMessage.TypeEnum.FIND_OPPONENT.getCode());
        message.setUser(new OpponentBO().setUsername(this.username).setHeadIcon(this.headIcon).setLevel(this.level));
        message.setOpponent(new OpponentBO().setUsername(opponent.username).setHeadIcon(opponent.headIcon).setLevel(opponent.level));

        try {
            session.getBasicRemote().sendText(JSONObject.toJSONString(message));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
